package com.wx.v3;


import com.motu.vertx.module.utility.toolset.TimeUtils;
import com.motu.vertx.module.utility.toolset.Tool;
import com.wechat.pay.java.core.RSAConfig;
import com.wechat.pay.java.core.cipher.Signer;
import com.wechat.pay.java.core.exception.ServiceException;
import com.wechat.pay.java.core.util.NonceUtil;
import com.wechat.pay.java.service.payments.app.AppService;
import com.wechat.pay.java.service.payments.h5.H5Service;
import com.wechat.pay.java.service.payments.jsapi.JsapiService;
import com.wechat.pay.java.service.payments.nativepay.NativePayService;


import io.vertx.core.json.JsonObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class PayTool {
    private static final Logger logger = LoggerFactory.getLogger(PayTool.class);

    /**
     *  初始化商户配置
     * @param merchantId  商户号
     * @param privateKeyPath 商户API私钥路径
     * @param merchantSerialNumber 商户证书序列号
     * @param wechatPayCertificatePath 平台证书文件地址
     * @return
     */
    public static RSAConfig initRSAConfig(String merchantId,String privateKeyPath,String merchantSerialNumber,String wechatPayCertificatePath) {
        RSAConfig config =
                new RSAConfig.Builder()
                        .merchantId(merchantId)
                        // 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥，商户私钥会用来生成请求的签名
                        .privateKeyFromPath(privateKeyPath)
                        .merchantSerialNumber(merchantSerialNumber)
                        .wechatPayCertificatesFromPath(wechatPayCertificatePath)
                        .build();
        return config;
    }

    /**
     * 初始App化服务
     * @param config 商户配置
     * @return
     */
    public static AppService initAppService(RSAConfig config) {
        AppService service = new AppService.Builder().config(config).build();
        return service;
    }

    /**
     * 初始H5化服务
     * @param config 商户配置
     * @return
     */
    public static H5Service initH5Service(RSAConfig config) {
        H5Service service = new H5Service.Builder().config(config).build();
        return service;
    }

    /**
     * 初始NativePay化服务
     * @param config 商户配置
     * @return
     */
    public static NativePayService initNativePayService(RSAConfig config) {
        NativePayService service = new NativePayService.Builder().config(config).build();
        return service;
    }

    /**
     * 初始Jsapi化服务
     * @param config 商户配置
     * @return
     */
    public static JsapiService initJsapiService(RSAConfig config) {
        JsapiService service = new JsapiService.Builder().config(config).build();
        return service;
    }


    /**
     * APP支付下单
     * @param appPayInfo
     * @return
     */
    public static JsonObject appPrepay(JsonObject appPayInfo) {
        JsonObject result = new JsonObject();
        try{
            //以下必填参数
            String merchantId = appPayInfo.getString("merchantId");//商户ID
            String privateKeyPath = appPayInfo.getString("privateKeyPath");//商户API私钥路径
            String merchantSerialNumber = appPayInfo.getString("merchantSerialNumber");//商户证书序列号
            String wechatPayCertificatePath = appPayInfo.getString("wechatPayCertificatePath");//商户证书序列号
            String appid = appPayInfo.getString("appid");//appid
            String description = appPayInfo.getString("description");//商品描述 string[1,127]
            String out_trade_no = appPayInfo.getString("out_trade_no");//订单id string[6,32]
            String notify_url = appPayInfo.getString("notify_url");// 回调地址
            int money = appPayInfo.getInteger("money");//金额(单位/分)
            String attach = appPayInfo.getString("attach");// 附加参数
            //非必填参数

            RSAConfig config = initRSAConfig(merchantId,privateKeyPath,merchantSerialNumber,wechatPayCertificatePath);//初始化商户配置
            AppService service = initAppService(config);//初始化service

            com.wechat.pay.java.service.payments.app.model.PrepayRequest request = new com.wechat.pay.java.service.payments.app.model.PrepayRequest();
            request.setAppid(appid);
            request.setMchid(merchantId);
            request.setDescription(description);
            request.setOutTradeNo(out_trade_no);
            request.setNotifyUrl(notify_url);
            request.setAttach(attach);//附加数据 在查询API和支付通知中原样返回
            com.wechat.pay.java.service.payments.app.model.Amount amount = new com.wechat.pay.java.service.payments.app.model.Amount();
            amount.setTotal(money);
            request.setAmount(amount);
            com.wechat.pay.java.service.payments.app.model.PrepayResponse appPrepayResponse = getPrepayIdByAppPrepay(service,request);
            com.wechat.pay.java.service.payments.app.model.PrepayWithRequestPaymentResponse appPrepayWithRequestPaymentResponse = appPrepay(appPrepayResponse.getPrepayId(),config,request);
            result.put("merchant_id",merchantId);
            result.put("prepay_id",appPrepayWithRequestPaymentResponse.getPrepayId());
            result.put("noncestr",appPrepayWithRequestPaymentResponse.getNonceStr());
            result.put("timestamp",appPrepayWithRequestPaymentResponse.getTimestamp());
            result.put("sign",appPrepayWithRequestPaymentResponse.getSign());
            return  result;
//            try {
//
//            } catch (HttpException e) { // 发送HTTP请求失败
//                // 调用e.getHttpRequest()获取请求打印日志或上报监控，更多方法见HttpException定义
//            } catch (ServiceException e) { // 服务返回状态小于200或大于等于300，例如500
//                // 调用e.getResponseBody()获取返回体打印日志或上报监控，更多方法见ServiceException定义
//            } catch (MalformedMessageException e) { // 服务返回成功，返回体类型不合法，或者解析返回体失败
//                // 调用e.getMessage()获取信息打印日志或上报监控，更多方法见MalformedMessageException定义
//            }
        } catch (ServiceException e) { // 服务返回状态小于200或大于等于300，例如500
            // 调用e.getResponseBody()获取返回体打印日志或上报监控，更多方法见ServiceException定义
            logger.error("### appPrepay errorCode!!! appPayInfo:"+appPayInfo.toString()+" httpResponseBody:"+ e.getResponseBody());
            result.put("errorCode",e.getErrorCode());
            result.put("errorMsg",e.getErrorMessage());
            return result;
        } catch (Exception e) {
            logger.error("### appPrepay error!!! appPayInfo:"+appPayInfo.toString()+" error:"+ Tool.getException(e));
            result.put("errorCode",999);
            return result;
        }
    }

    /**
     * APP支付下单
     * @param service appService服务
     * @param appid   appid
     * @param merchantId  商户ID
     * @param description 商品描述 string[1,127]
     * @param out_trade_no 订单id string[6,32]
     * @param notify_url  回调地址
     * @param money  金额(单位/分)
     * @return
     */

    /**
     * APP支付下单-获取微信下单id
     * @param service
     * @param request
     * @return
     */
    public static com.wechat.pay.java.service.payments.app.model.PrepayResponse getPrepayIdByAppPrepay(AppService service,com.wechat.pay.java.service.payments.app.model.PrepayRequest request) {
        return service.prepay(request);
    }

    /**
     * APP支付下单-返回调支付的加密信息
     * @param prepayId
     * @param config
     * @param request
     * @return
     */
    public static com.wechat.pay.java.service.payments.app.model.PrepayWithRequestPaymentResponse appPrepay(String prepayId, RSAConfig config, com.wechat.pay.java.service.payments.app.model.PrepayRequest request) {
        Signer signer = config.createSigner();

        String timestamp = String.valueOf(TimeUtils.getCurTime());
        String nonceStr = NonceUtil.createNonce(32);
        String message =
                request.getAppid() + "\n" + timestamp + "\n" + nonceStr + "\n" + prepayId + "\n";
//        logger.debug("Message for RequestPayment signatures is[{}]", message);
        String sign = signer.sign(message).getSign();
        com.wechat.pay.java.service.payments.app.model.PrepayWithRequestPaymentResponse response = new com.wechat.pay.java.service.payments.app.model.PrepayWithRequestPaymentResponse();
        response.setAppid(request.getAppid());
        response.setPartnerId(request.getMchid());
        response.setPrepayId(prepayId);
        response.setPackageVal("Sign=WXPay");
        response.setNonceStr(nonceStr);
        response.setTimestamp(timestamp);
        response.setSign(sign);
        return response;
    }

    /**
     * H5支付下单
     * @param h5PayInfo
     * @return
     */
    public static JsonObject h5Prepay(JsonObject h5PayInfo) {
        JsonObject result = new JsonObject();
        try{
            //以下必填参数
            String merchantId = h5PayInfo.getString("merchantId");//商户ID
            String privateKeyPath = h5PayInfo.getString("privateKeyPath");//商户API私钥路径
            String merchantSerialNumber = h5PayInfo.getString("merchantSerialNumber");//商户证书序列号
            String wechatPayCertificatePath = h5PayInfo.getString("wechatPayCertificatePath");//商户证书序列号
            String appid = h5PayInfo.getString("appid");//appid
            String description = h5PayInfo.getString("description");//商品描述 string[1,127]
            String out_trade_no = h5PayInfo.getString("out_trade_no");//订单id string[6,32]
            String notify_url = h5PayInfo.getString("notify_url");// 回调地址
            int money = h5PayInfo.getInteger("money");//金额(单位/分)
            String payerClientIp = h5PayInfo.getString("payerClientIp");// 用户终端IP
            String h5_type = h5PayInfo.getString("h5_type");// 场景类型(示例值：iOS, Android, Wap)
            String attach = h5PayInfo.getString("attach");// 附加参数
            //非必填参数

            RSAConfig config = initRSAConfig(merchantId,privateKeyPath,merchantSerialNumber,wechatPayCertificatePath);//初始化商户配置
            H5Service service = initH5Service(config);//初始化service
            com.wechat.pay.java.service.payments.h5.model.PrepayResponse prepayResponse =  h5Prepay(service,appid,merchantId,description,out_trade_no,notify_url,money,payerClientIp,h5_type,attach);
            String H5Url = prepayResponse.getH5Url();
            if(!Tool.isEmpty(h5PayInfo.getString("redirectUrl"))){
                H5Url += "&redirect_url=" + h5PayInfo.getString("redirectUrl");
            }
            result.put("H5Url",H5Url);
            result.put("Referer",h5PayInfo.getString("h5Referer"));//切支付客户端Headers需要设置Referer
            return  result;
        } catch (ServiceException e) { // 服务返回状态小于200或大于等于300，例如500
            // 调用e.getResponseBody()获取返回体打印日志或上报监控，更多方法见ServiceException定义
            logger.error("### h5Prepay errorCode!!! h5PayInfo:"+h5PayInfo.toString()+" httpResponseBody:"+ e.getResponseBody());
            result.put("errorCode",e.getErrorCode());
            result.put("errorMsg",e.getErrorMessage());
            return result;
        } catch (Exception e) {
            logger.error("### h5Prepay error!!! h5PayInfo:"+h5PayInfo.toString()+" error:"+ Tool.getException(e));
            result.put("errorCode",999);
            return result;
        }
    }

    /**
     * H5支付下单
     * @param service h5Service服务
     * @param appid  appid
     * @param merchantId  商户ID
     * @param description  商品描述 string[1,127]
     * @param out_trade_no 订单id string[6,32]
     * @param notify_url 回调地址
     * @param money 金额(单位/分)
     * @param payerClientIp 用户终端IP
     * @param type 场景类型(示例值：iOS, Android, Wap)
     * @return
     */
    public static com.wechat.pay.java.service.payments.h5.model.PrepayResponse h5Prepay(H5Service service,String appid,String merchantId,String description,String out_trade_no,String notify_url,int money,String payerClientIp,String type,String attach) {
        com.wechat.pay.java.service.payments.h5.model.PrepayRequest request = new com.wechat.pay.java.service.payments.h5.model.PrepayRequest();
        request.setAppid(appid);
        request.setMchid(merchantId);
        request.setDescription(description);
        request.setOutTradeNo(out_trade_no);
        request.setNotifyUrl(notify_url);
		request.setAttach(attach);//附加数据 在查询API和支付通知中原样返回
        com.wechat.pay.java.service.payments.h5.model.Amount amount = new com.wechat.pay.java.service.payments.h5.model.Amount();
        amount.setTotal(money);
        request.setAmount(amount);
        com.wechat.pay.java.service.payments.h5.model.SceneInfo sceneInfo = new com.wechat.pay.java.service.payments.h5.model.SceneInfo();
        sceneInfo.setPayerClientIp(payerClientIp);
        com.wechat.pay.java.service.payments.h5.model.H5Info h5Info = new com.wechat.pay.java.service.payments.h5.model.H5Info();
        h5Info.setType(type);
        sceneInfo.setH5Info(h5Info);
        request.setSceneInfo(sceneInfo);
        return service.prepay(request);
    }

    /**
     * H5支付查询订单
     * @param h5CheckInfo
     * @return
     */
    public static JsonObject h5Chck(JsonObject h5CheckInfo) {
        JsonObject result = new JsonObject();
        try{
            //以下必填参数
            String merchantId = h5CheckInfo.getString("merchantId");//商户ID
            String privateKeyPath = h5CheckInfo.getString("privateKeyPath");//商户API私钥路径
            String merchantSerialNumber = h5CheckInfo.getString("merchantSerialNumber");//商户证书序列号
            String wechatPayCertificatePath = h5CheckInfo.getString("wechatPayCertificatePath");//商户证书序列号

            RSAConfig config = initRSAConfig(merchantId,privateKeyPath,merchantSerialNumber,wechatPayCertificatePath);//初始化商户配置
            H5Service service = initH5Service(config);//初始化service
            if (h5CheckInfo.containsKey("out_trade_no")) {
                String out_trade_no = h5CheckInfo.getString("out_trade_no");//订单id string[6,32]
                com.wechat.pay.java.service.payments.model.Transaction checkResponse =  h5QueryOrderByOutTradeNo(service,merchantId,out_trade_no);
                result.put("out_trade_no",checkResponse.getOutTradeNo());
                result.put("trade_state",checkResponse.getTradeState());
                result.put("attach",checkResponse.getAttach());

            } else if (h5CheckInfo.containsKey("transactionId")) {
                String transactionId = h5CheckInfo.getString("transactionId");//微信订单id string[6,32]
                com.wechat.pay.java.service.payments.model.Transaction checkResponse =  queryOrderById(service,merchantId,transactionId);
                result.put("transaction_id",checkResponse.getTransactionId());
                result.put("trade_state",checkResponse.getTradeState());
                result.put("attach",checkResponse.getAttach());
            }
            return  result;
//        } catch (HttpException e) { // 发送HTTP请求失败
//            // 调用e.getHttpRequest()获取请求打印日志或上报监控，更多方法见HttpException定义
        } catch (ServiceException e) { // 服务返回状态小于200或大于等于300，例如500
            // 调用e.getResponseBody()获取返回体打印日志或上报监控，更多方法见ServiceException定义
            logger.error("### h5Chck errorCode!!! h5CheckInfo:"+h5CheckInfo.toString()+" httpResponseBody:"+ e.getResponseBody());
            result.put("errorCode",e.getErrorCode());
            result.put("errorMsg",e.getErrorMessage());
            return result;
//        } catch (MalformedMessageException e) { // 服务返回成功，返回体类型不合法，或者解析返回体失败
//            // 调用e.getMessage()获取信息打印日志或上报监控，更多方法见MalformedMessageException定义
        } catch (Exception e) {
            logger.error("### h5Chck error!!! h5CheckInfo:"+h5CheckInfo.toString()+" error:"+ Tool.getException(e));
            result.put("errorCode",999);
            return result;
        }
    }

    /**
     *微信支付订单号查询订单
     * @param service
     * @param merchantId 商户ID
     * @param transactionId 微信订单ID
     * @return
     */
    public static com.wechat.pay.java.service.payments.model.Transaction queryOrderById(H5Service service,String merchantId,String transactionId) {
        com.wechat.pay.java.service.payments.h5.model.QueryOrderByIdRequest request = new com.wechat.pay.java.service.payments.h5.model.QueryOrderByIdRequest();
        // 调用request.setXxx(val)设置所需参数，具体参数可见Request定义
        request.setMchid(merchantId);
        request.setTransactionId(transactionId);
        // 调用接口
        return service.queryOrderById(request);
    }

    /**
     * 商户订单号查询订单
     * @param service
     * @param merchantId 商户ID
     * @param out_trade_no 商家订单ID
     * @return
     */
    public static com.wechat.pay.java.service.payments.model.Transaction h5QueryOrderByOutTradeNo(H5Service service,String merchantId,String out_trade_no) {
        com.wechat.pay.java.service.payments.h5.model.QueryOrderByOutTradeNoRequest request = new com.wechat.pay.java.service.payments.h5.model.QueryOrderByOutTradeNoRequest();
        // 调用request.setXxx(val)设置所需参数，具体参数可见Request定义
        request.setMchid(merchantId);
        request.setOutTradeNo(out_trade_no);
        // 调用接口
        return service.queryOrderByOutTradeNo(request);
    }

    /**
     * Native支付下单
     * @param nativePayInfo
     * @return
     */
    public static JsonObject nativepayPrepay(JsonObject nativePayInfo) {
        JsonObject result = new JsonObject();
        try{
            //以下必填参数
            String merchantId = nativePayInfo.getString("merchantId");//商户ID
            String privateKeyPath = nativePayInfo.getString("privateKeyPath");//商户API私钥路径
            String merchantSerialNumber = nativePayInfo.getString("merchantSerialNumber");//商户证书序列号
            String wechatPayCertificatePath = nativePayInfo.getString("wechatPayCertificatePath");//商户证书序列号
            String appid = nativePayInfo.getString("appid");//appid
            String description = nativePayInfo.getString("description");//商品描述 string[1,127]
            String out_trade_no = nativePayInfo.getString("out_trade_no");//订单id string[6,32]
            String notify_url = nativePayInfo.getString("notify_url");// 回调地址
            int money = nativePayInfo.getInteger("money");//金额(单位/分)
            String attach = nativePayInfo.getString("attach");// 附加参数
            //非必填参数

            RSAConfig config = initRSAConfig(merchantId,privateKeyPath,merchantSerialNumber,wechatPayCertificatePath);//初始化商户配置
            NativePayService service = initNativePayService(config);//初始化service
            com.wechat.pay.java.service.payments.nativepay.model.PrepayResponse prepayResponse =  nativepayPrepay(service,appid,merchantId,description,out_trade_no,notify_url,money,attach);
            result.put("CodeUrl",prepayResponse.getCodeUrl());
            return  result;
        } catch (ServiceException e) { // 服务返回状态小于200或大于等于300，例如500
            // 调用e.getResponseBody()获取返回体打印日志或上报监控，更多方法见ServiceException定义
            logger.error("### nativepayPrepay errorCode!!! nativePayInfo:"+nativePayInfo.toString()+" httpResponseBody:"+ e.getResponseBody());
            result.put("errorCode",e.getErrorCode());
            result.put("errorMsg",e.getErrorMessage());
            return result;
        } catch (Exception e) {
            logger.error("### nativepayPrepay error!!! nativePayInfo:"+nativePayInfo.toString()+" error:"+ Tool.getException(e));
            result.put("errorCode",999);
            return result;
        }
    }

    /**
     * Native支付下单
     * @param service NativePayService服务
     * @param appid   appid
     * @param merchantId  商户ID
     * @param description 商品描述 string[1,127]
     * @param out_trade_no 订单id string[6,32]
     * @param notify_url  回调地址
     * @param money  金额(单位/分)
     * @return
     */
    public static com.wechat.pay.java.service.payments.nativepay.model.PrepayResponse nativepayPrepay(NativePayService service,String appid,String merchantId,String description,String out_trade_no,String notify_url,int money,String attach) {
        com.wechat.pay.java.service.payments.nativepay.model.PrepayRequest request = new com.wechat.pay.java.service.payments.nativepay.model.PrepayRequest();
        request.setAppid(appid);
        request.setMchid(merchantId);
        request.setDescription(description);
        request.setOutTradeNo(out_trade_no);
        request.setNotifyUrl(notify_url);
		request.setAttach(attach);//附加数据 在查询API和支付通知中原样返回
        com.wechat.pay.java.service.payments.nativepay.model.Amount amount = new com.wechat.pay.java.service.payments.nativepay.model.Amount();
        amount.setTotal(money);
        request.setAmount(amount);
        return service.prepay(request);
    }

    /**
     * jsapi支付下单
     * @param jsapiPayInfo
     * @return
     */
    public static JsonObject jsapiPrepay(JsonObject jsapiPayInfo) {
        JsonObject result = new JsonObject();
        try{
            //以下必填参数
            String merchantId = jsapiPayInfo.getString("merchantId");//商户ID
            String privateKeyPath = jsapiPayInfo.getString("privateKeyPath");//商户API私钥路径
            String merchantSerialNumber = jsapiPayInfo.getString("merchantSerialNumber");//商户证书序列号
            String wechatPayCertificatePath = jsapiPayInfo.getString("wechatPayCertificatePath");//商户证书序列号
            String appid = jsapiPayInfo.getString("appid");//appid
            String description = jsapiPayInfo.getString("description");//商品描述 string[1,127]
            String out_trade_no = jsapiPayInfo.getString("out_trade_no");//订单id string[6,32]
            String notify_url = jsapiPayInfo.getString("notify_url");// 回调地址
            int money = jsapiPayInfo.getInteger("money");//金额(单位/分)
            String openid = jsapiPayInfo.getString("openid");// openid
            //非必填参数

            RSAConfig config = initRSAConfig(merchantId,privateKeyPath,merchantSerialNumber,wechatPayCertificatePath);//初始化商户配置
            JsapiService service = initJsapiService(config);//初始化service


            com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest request = new com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest();
            request.setAppid(appid);//appid
            request.setMchid(merchantId);//商户ID
            request.setDescription(description);//商品描述 string[1,127]
            request.setOutTradeNo(out_trade_no);//订单id string[6,32]
            request.setNotifyUrl(notify_url);//回调地址
//    		request.setAttach(attach);//附加数据 在查询API和支付通知中原样返回
            com.wechat.pay.java.service.payments.jsapi.model.Amount amount = new com.wechat.pay.java.service.payments.jsapi.model.Amount();
            amount.setTotal(money);// 金额(单位/分)
            request.setAmount(amount);
            com.wechat.pay.java.service.payments.jsapi.model.Payer payer = new com.wechat.pay.java.service.payments.jsapi.model.Payer();
            payer.setOpenid(openid);//openid
            request.setPayer(payer);

            com.wechat.pay.java.service.payments.jsapi.model.PrepayResponse jsapiPrepayResponse =  jsapiPrepay(service,request);
            String PrepayId = jsapiPrepayResponse.getPrepayId();
            com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse prepayResponse =  jsapiPrepay(PrepayId,config,request);

            result.put("prepayId",PrepayId);
            result.put("appId",prepayResponse.getAppId());
            result.put("nonceStr",prepayResponse.getNonceStr());
            result.put("timeStamp",prepayResponse.getTimeStamp());
            result.put("packageVal",prepayResponse.getPackageVal());
            result.put("signType",prepayResponse.getSignType());
            result.put("paySign",prepayResponse.getPaySign());
            return  result;
        } catch (Exception e) {
            logger.error("### jsapiPrepay error!!! jsapiPayInfo:"+jsapiPayInfo.toString()+" error:"+ Tool.getException(e));
            result.put("errorCode",999);
            return result;
        }
    }

    /**
     * jsapi支付下单
     * @return
     */
    public static com.wechat.pay.java.service.payments.jsapi.model.PrepayResponse jsapiPrepay(JsapiService service,com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest request) {
        return service.prepay(request);
    }

    /**
     * jsapi支付下单-返回调支付的加密信息
     * @param prepayId
     * @param config
     * @param request
     * @return
     */
    public static com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse jsapiPrepay(String prepayId, RSAConfig config, com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest request) {
        Signer signer = config.createSigner();

        String timestamp = String.valueOf(TimeUtils.getCurTime());
        String nonceStr = NonceUtil.createNonce(32);
        String packageVal = "prepay_id=" + prepayId;

        String message =
                request.getAppid() + "\n" + timestamp + "\n" + nonceStr + "\n" + packageVal + "\n";
        String sign = signer.sign(message).getSign();

        com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse response = new com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse();
        response.setAppId(request.getAppid());
        response.setTimeStamp(timestamp);
        response.setNonceStr(nonceStr);//随机字符串，不长于32位。
        response.setPackageVal(packageVal);//JSAPI下单接口返回的prepay_id参数值，提交格式如：prepay_id=***
        response.setSignType("RSA");//签名类型，默认为RSA，仅支持RSA
        response.setPaySign(sign);
        return response;
    }


//    /**
//     * 解密resource
//     * @return
//     */
//    public static boolean checkHttpByWxV3(String merchantId,String privateKeyPath,String merchantSerialNumber,String wechatPayCertificatePath,String apiV3Key, String wechatPaySerial,String wechatpayNonce,String wechatSignature,String wechatTimestamp,String requestBody) {
//        try {
//            Config config = initRSAConfig(merchantId,privateKeyPath,merchantSerialNumber,wechatPayCertificatePath);//初始化商户配置
//
//            RequestParam requestParam = new RequestParam.Builder()
//                    .serialNumber(wechatPaySerial)
//                    .nonce(wechatpayNonce)
//                    .signature(wechatSignature)
//                    .timestamp(wechatTimestamp)
//                    .body(requestBody)
//                    .build();
//
//            // 没有的话，则构造一个
//
//            // 初始化 NotificationParser
//            NotificationParser parser = new NotificationParser((NotificationConfig) config);
//            Transaction transaction = parser.parse(requestParam, Transaction.class);
//            System.out.println("checkHttpByWxV3: transaction = " +transaction.toString() + " transaction.getOutTradeNo = " + transaction.getOutTradeNo() );
//        } catch (ValidationException e) {
//            // 签名验证失败，返回 401 UNAUTHORIZED 状态码
//            logger.error("sign verification failed", e);
//            return false;
////            return ResponseEntity.status(HttpStatus.UNAUTHORIZED);
//        } catch (Exception e) {
//            e.printStackTrace();
//            return false;
//        }
//        return true;
////// 如果处理失败，应返回 4xx/5xx 的状态码，例如 500 INTERNAL_SERVER_ERROR
////        if (/* process error */) {
//////            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR);
////        }
//    }

    /**
     * 解密resource
     * @param apiV3key
     * @param msg
     * @param nonce
     * @param associated_data
     * @return
     */
    public static String decryptWxResource(String apiV3key,String msg,String nonce,String associated_data) {
        try {
            /**
             * 1、用商户平台上设置的APIv3密钥【微信商户平台—>账户设置—>API安全—>设置APIv3密钥】，记为key；
             * 2、针对resource.algorithm中描述的算法（目前为AEAD_AES_256_GCM），取得对应的参数nonce和associated_data；
             * 3、使用key、nonce和associated_data，对数据密文resource.ciphertext进行解密，得到JSON形式的资源对象；
             */
            Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
            byte[] decode = Base64.getDecoder().decode(msg);

            cipher.init(2, new SecretKeySpec(apiV3key.getBytes(), "AES"), new GCMParameterSpec(128, nonce.getBytes()));
            if (!Tool.isEmpty(associated_data)) {
                cipher.updateAAD(associated_data.getBytes());
            }
            String str = new String(cipher.doFinal(decode), StandardCharsets.UTF_8);
            return str;
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }
}
